<?php
namespace Twoir\Service;

use Exception;

use function array_filter;
use function array_walk_recursive;
use function basename;
use function class_exists;
use function constant;
use function forward_static_call_array;
use function is_numeric;
use function nl2br;
use function scandir;
use function strtolower;
use function str_contains;

/**
 * 模型信息调用入口
 *
 * cighsen02 365182575
 *
 * Create at: 2025.01.21
 * Update at: 2025.05.08
*/
class BaseInfo
{
	// 当前操作的表
	protected ?string $tablename = null;

	protected ?int $tid = null;

	protected ?int $mid = null;

	// 父栏目id
	protected ?int $bclassid = null;

	// 当前栏目id
	protected ?int $classid = null;

	/**
	 * 栏目id
	 *
	 * @param int|null $classid
	 */
	public function __construct($classid = null)
	{
        $this->initialize($classid);
	}

    /**
	 * 重设置classid
	 *
	 * @param int $classid
	 * @return static
	*/
	public function setClassId(int $classid)
	{
		// 如果与旧相同，跳过
		if ($classid && $classid !== $this->classid) {
			// 重置
			$this->tablename 	= null;
			$this->tid			= null;
			$this->mid			= null;
			$this->bclassid 	= null;

			$this->initialize($classid);
		}

		return $this;
	}

    /**
     * 重设置tablename
     *
     * @param string $tablename
     * @return static
    */
    public function setTableName(string $tablename)
    {
    	// 如果与旧相同，跳过
    	if ($tablename && strtolower($tablename) !== strtolower($this->tablename)) {
    		// 重置
    		$this->tablename 	= null;
			$this->tid			= null;
			$this->mid			= null;
    		$this->bclassid 	= null;

    		$this->initialize($tablename);
    	}

    	return $this;
    }

	/**
	 * 返回查询条件
     *
     * @param int $classid
     * @return array
	*/
	public function getWhere(int $classid): array
	{
	    global $class_r;

	    // 顶级栏目
	    if(0 === $this->bclassid) return [];

	    // 非终级栏目
	    if($classid && isset($class_r[$classid]['islast'], $class_r[$classid]['islist']) && 0 === $class_r[$classid]['islast'] && 1 === $class_r[$classid]['islist']) {

	        $str = $class_r[$classid]['sonclass'] ? trim($class_r[$classid]['sonclass'], '|') : $classid;

	        return str_contains($str, '|') ? ['classid in' => explode('|', $str)] : ['classid' => $classid];
	    }

	    // 终级栏目
	    return ['classid' => $classid];
	}

    /**
	 * 统计
	 *
	 * @param array $where
	 * @param string $field
	 * @param int $type
	 * @return int
     *
     * @throws Exception
	 */
	public function getCount(array $where, string $field = '', $type = '')
	{
		if (empty($this->tablename)) throw new Exception('数据库不存在', 9200);

        if (!class_exists('Twoir\System\Model\\' . $this->tablename)) throw new Exception('请先建立模型，再操作', 9200);

		return forward_static_call_array(['Twoir\System\Model\\' . $this->tablename, __FUNCTION__], [$where, $field, $type]);
	}

	/**
	 * 单条信息
	 *
	 * @param array $where 条件
	 * @param array $field 要取的字段名
     * @param string $groupby
     * @param string $orderby
	 * @param string $type
	 * @return array
	*/
	public function getOne(array $where, array $field = ['*'], string $groupby = '', string $orderby = '', string $type = ''): array
	{
        if (empty($this->tablename)) throw new Exception('数据库不存在', 9200);

        if (!class_exists('Twoir\System\Model\\' . $this->tablename)) throw new Exception('请先建立模型，再操作', 9200);

		return forward_static_call_array(['Twoir\System\Model\\' . $this->tablename, 'getOne'], [$where, $field, $groupby, $orderby, $type]);
	}

	/**
	 * 多条信息
	 *
	 * @param array $where 条件
	 * @param array $field 要取的字段名
     * @param string $groupby
     * @param string $orderby
     * @param int $limit
     * @param int $pagesize
     * @param int $page
	 * @param string $type
	 * @return array
	*/
	public function getList(array $where, array $field = ['*'], string $groupby = '', string $orderby = '', int $limit = 0, int $pagesize = 10, int $page = 0, string $type = '')
	{
        if (empty($this->tablename)) throw new Exception('数据库不存在', 9200);

        if (!class_exists('Twoir\System\Model\\' . $this->tablename)) throw new Exception('请先建立模型，再操作', 9200);

		return forward_static_call_array(['Twoir\System\Model\\' . $this->tablename, 'getList'], [$where, $field, $groupby, $orderby, $limit, $pagesize, $page, $type]);
	}

	/**
     * 插入交易信息
	 *
     * @param array $add
	 * @param string $type
     * @return int 0为失败，成功返回当前id
    */
	public function insert(array $add = [], string $type = ''): int
    {
        if (empty($this->tablename)) throw new Exception('数据库不存在', 9200);

        if (!class_exists('Twoir\System\Model\\' . $this->tablename)) throw new Exception('请先建立模型，再操作', 9200);

        return forward_static_call_array(['Twoir\System\Model\\' . $this->tablename, 'insert'], [$add, $type]);
    }

	/**
     * 更新
	 *
	 * @param array $where
	 * @param array $add
	 * @param int $limit
	 * @param string $type
	 * @return bool
     **/
    public function update(array $where = [], array $add = [], int $limit = 0, string $type = ''): bool
	{
        if (empty($this->tablename)) throw new Exception('数据库不存在', 9200);

        if (!class_exists('Twoir\System\Model\\' . $this->tablename)) throw new Exception('请先建立模型，再操作', 9200);

		return forward_static_call_array(['Twoir\System\Model\\' . $this->tablename, 'update'], [$where, $add, $limit, $type]);
	}

    /**
     * 获得模型名称
     *
     * @return string
     */
    public function modelName()
    {
        if (empty($this->tablename)) throw new Exception('初始化失败', 9200);

        return constant('Twoir\System\Model\\' . $this->tablename . '::MODEL');
    }

    /**
	 * 格式化数据
	 *
	 * @param array $data
	 * @return array
	*/
	protected function format(array $data)
	{
		global $emod_r;

		if (empty($data)) return [];

		array_walk_recursive($data, function (&$value, $key) use($emod_r) {
			// 时间
			if (in_array($key, ['newstime', 'truetime', 'lastdotime'])) {
				// Y-m-d H:i:s
				$value = date('Y-m-d', $value);
			}
            // 拼上域名
			elseif ($key === 'titleurl') {
			    $value = eReturnDomain() . $value;
			}
			else{
				// 转义
				if (!str_contains($emod_r[$this->mid]['editorf'], ',' . $key . ',')) {
					// 加br
					if(str_contains($emod_r[$this->mid]['tobrf'], ',' . $key . ',')){

						$value = nl2br($value);
					}
					// 去除html
					if(!str_contains($emod_r[$this->mid]['dohtmlf'], ',' . $key . ',')){

						$value = RepFieldtextNbsp(ehtmlspecialchars($value));
					}
				}
			}
		});

		return $data;
	}

    /**
	 * 初始化
	 *
	 * @param string|int $classid
	*/
	protected function initialize($classid = null)
	{
        global $class_r, $etable_r;

        if ($classid && !is_numeric($classid)) {

            $this->tablename 	= $this->methodName($classid);
			$this->mid 			= $this->tablename ? ($etable_r[$this->tablename]['mid'] ?? null) : null;
        }
        elseif ($classid && isset($class_r[$classid]['tbname'])) {

            if (empty($class_r[$classid]['tbname'])) throw new Exception("参数错误!", 9200);

            $this->tablename    = $this->methodName($class_r[$classid]['tbname']);
            $this->tid			= $class_r[$classid]['tid'] ?? null;
            $this->mid			= $class_r[$classid]['modid'] ?? null;;
            $this->bclassid     = $class_r[$classid]['bclassid'] ?? null;
            $this->classid      = $classid;
        }
	}

	/**
	 * 确定方法简短名称
	 *
	 * @param string $method 调用方法
	 * @return string|null 返回实际方法名
	*/
	protected function methodName(string $method): ?string
	{
		$method = pascal_case($method);

		foreach (array_filter(scandir(dirname(__DIR__) . DIRECTORY_SEPARATOR . 'System' . DIRECTORY_SEPARATOR . 'Model'), fn($item) => '.' !== $item && '..' !== $item) as $item) {

			$item = basename($item, '.php');
			if (strtolower($method) === strtolower($item)) return $item;
		}

		return null;
	}
}
